﻿using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.CommonBot.Routines;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Action = Styx.TreeSharp.Action;

namespace BMSVMM
{
    public partial class Main : CombatRoutine
    {
        #region Beastmaster Rotation
        
        Composite SerpentRotation()
        {
            return new PrioritySelector(
                Cast("Serpent Sting", ret => gotTarget)
                );
        }
        Composite BMRotation()
        {
            return new PrioritySelector(
                new Decorator(ret => gotTarget && DoAoe, CreateBMAoe()),
                    new Decorator(ret => gotTarget && CRSettingsBMSVMM.myPrefs.MisdirectChoice == CRSettingsBMSVMM.Misdirect.Auto && LastSpell != "Misdirection", CreateMisdirectionBehavior()),
                    new Decorator(ret => gotTarget && !DoAoe,
                        new PrioritySelector(
                        Cast("Revive Pet", ret => StyxWoW.Me.Pet != null && StyxWoW.Me.Pet.IsDead),
                        Cast("Mend Pet", ret => StyxWoW.Me.GotAlivePet
                            && StyxWoW.Me.Pet.HealthPercent <= CRSettingsBMSVMM.myPrefs.useMendPet && !StyxWoW.Me.Pet.HasAura("Mend Pet")),
                        Cast("Disengage", ret => gotTarget && Me.CurrentTarget.Distance <= CRSettingsBMSVMM.myPrefs.DisengageDistance && CRSettingsBMSVMM.myPrefs.DisengageDistance != 0 && !spellOnCooldown("Disengage")),
                        new Decorator(ret => gotTarget && !debuffExists("Serpent Sting", Me.CurrentTarget) && LastSpell != "Serpent Sting", SerpentRotation()),
                        Cast("Focus Fire", ret => gotTarget && buffExists("Frenzy", Me) && buffStackCount("Frenzy", Me) >= 5),
                        Cast("Bestial Wrath", ret => gotTarget && !spellOnCooldown("Bestial Wrath") && !buffExists("Focus Fire", Me)),
                        Cast("Kill Command", ret => gotTarget 
                            && !spellOnCooldown("Kill Command")
                            && Me.GotAlivePet
                            && Me.Pet.IsWithinMeleeRangeOf(Me.CurrentTarget)),
                        new Decorator(ret => gotTarget && buffExists(THRILL_OF_THE_HUNT, Me), ThrillRoation()),
                        CreateTalent60Behavior(),
                        Cast("Counter Shot", ret => gotTarget && !spellOnCooldown("Counter Shot") && Me.CurrentTarget.IsCasting && Me.CanInterruptCurrentSpellCast),
                        Cast("Concussive Shot", ret => gotTarget && !debuffExists("Concussive Shot", StyxWoW.Me.CurrentTarget) && Me.CurrentTarget.IsPlayer),
                        Cast("Concussive Shot", ret => gotTarget && !debuffExists("Concussive Shot", StyxWoW.Me.CurrentTarget) && Me.CurrentTarget.ThreatInfo.RawPercent > 90 && !Me.CurrentTarget.Name.Contains("Dummy")),
                        Cast("Concussive Shot", ret => gotTarget && StyxWoW.Me.MovementInfo.MovingBackward && !debuffExists("Concussive Shot", StyxWoW.Me.CurrentTarget)),
                        DropCastOnMe("Ice Trap", ret => gotTarget
                            && CRSettingsBMSVMM.myPrefs.Kiting
                            && StyxWoW.Me.MovementInfo.MovingBackward && StyxWoW.Me.HasAura("Trap Launcher") && !spellOnCooldown("Ice Trap")),
                        Cast("Kill Shot", ret => gotTarget && StyxWoW.Me.CurrentTarget.HealthPercent <= 20 && !spellOnCooldown("Kill Shot")),

                Cast("Stampede", ret => gotTarget
                    && (!BurstKeySettings.myPrefs.useBurstMode || (BurstKeySettings.myPrefs.useBurstMode && !BurstKeySettings.myPrefs.useBurstStampede))
                    && isBoss
                    && !spellOnCooldown("Stampede")),
                Cast("Rapid Fire", ret => gotTarget
                    && (!BurstKeySettings.myPrefs.useBurstMode || (BurstKeySettings.myPrefs.useBurstRapidFire && !BurstKeySettings.myPrefs.useBurstRapidFire))
                    && isBoss
                    && !spellOnCooldown("Rapid Fire")
                    && LastSpell != "Rapid Fire"),
                Cast("Lifeblood", ret => gotTarget && isBoss && !spellOnCooldown("Lifeblood")),
                Cast("Blood Fury", ret => gotTarget
                    && CRSettingsBMSVMM.myPrefs.useBloodFury
                    && (!BurstKeySettings.myPrefs.useBurstMode || (BurstKeySettings.myPrefs.useBurstMode && !BurstKeySettings.myPrefs.useBurstBloodFury))
                    && isBoss
                    && !spellOnCooldown("Blood Fury")),
                Cast("Berserking", ret => gotTarget
                    && CRSettingsBMSVMM.myPrefs.useBerserking
                    && (!BurstKeySettings.myPrefs.useBurstMode || (BurstKeySettings.myPrefs.useBurstMode && !BurstKeySettings.myPrefs.useBurstBloodFury))
                    && isBoss
                    && !spellOnCooldown("Berserking")),
                //Burst Mode
                new Decorator(ret => gotTarget
                    && BurstEnabled
                    && SpellManager.HasSpell(RAPID_FIRE)
                    && !spellOnCooldown(RAPID_FIRE)
                    && BurstKeySettings.myPrefs.useBurstMode
                    && BurstKeySettings.myPrefs.useBurstRapidFire
                    && nextBurstSpellAllowed <= DateTime.Now, CastBurstRapidFire()),
                new Decorator(ret => gotTarget
                    && BurstEnabled
                    && SpellManager.HasSpell(STAMPEDE)
                    && !spellOnCooldown(STAMPEDE)
                    && BurstKeySettings.myPrefs.useBurstMode
                    && BurstKeySettings.myPrefs.useBurstStampede
                    && nextBurstSpellAllowed <= DateTime.Now, CastBurstStampede()),
                new Decorator(ret => gotTarget
                    && BurstEnabled
                    && BurstKeySettings.myPrefs.useBurstMode
                    && BurstKeySettings.myPrefs.useBurstCrows
                    && !spellOnCooldown(MURDER_OF_CROWS)
                    && nextBurstSpellAllowed <= DateTime.Now, CastBurstMurderOfCrows()),
                new Decorator(ret => gotTarget
                    && BurstEnabled
                    && BurstKeySettings.myPrefs.useBurstMode
                    && BurstKeySettings.myPrefs.useBurstBerserking
                    && !spellOnCooldown(BERSERKING)
                    && NotHaveHasteBuffs()
                    && nextBurstSpellAllowed <= DateTime.Now, CastBurstBerserking()),
                new Decorator(ret => gotTarget
                    && BurstEnabled
                    && BurstKeySettings.myPrefs.useBurstMode
                    && BurstKeySettings.myPrefs.useBurstBloodFury
                    && !spellOnCooldown(BLOOD_FURY)
                    && nextBurstSpellAllowed <= DateTime.Now, CastBurstBloodFury()),
                new Decorator(ret => gotTarget
                    && BurstEnabled
                    && BurstKeySettings.myPrefs.useBurstMode
                    && BurstKeySettings.myPrefs.useBurstTrinket1
                    && CRSettingsBMSVMM.myPrefs.Trinket1Use != CRSettingsBMSVMM.TrinketsUse.Manual
                    && nextTrinketUseAllowed <= DateTime.Now, Trinket1()),
                new Decorator(ret => gotTarget
                    && BurstEnabled
                    && BurstKeySettings.myPrefs.useBurstMode
                    && BurstKeySettings.myPrefs.useBurstTrinket2
                    && CRSettingsBMSVMM.myPrefs.Trinket2Use != CRSettingsBMSVMM.TrinketsUse.Manual
                    && nextTrinketUseAllowed <= DateTime.Now, Trinket2()),
                new Decorator(ret => gotTarget
                    && BurstEnabled
                    && BurstKeySettings.myPrefs.useBurstMode
                    && BurstKeySettings.myPrefs.useBurstEngiGloves
                    && CRSettingsBMSVMM.myPrefs.GlovesChoice != CRSettingsBMSVMM.useEngiGloves.Manual
                    && nextEngiGlovesUseAllowed <= DateTime.Now, EngineerGloves()),
                //end burstmode

                CreateTalent60Behavior(),
                CreateTalent75Behavior(),
                CreateTalent90Behavior(),

                new Decorator(ret => gotTarget
                    && (!BurstKeySettings.myPrefs.useBurstMode || (BurstKeySettings.myPrefs.useBurstMode && !BurstKeySettings.myPrefs.useBurstTrinket1))
                    && CRSettingsBMSVMM.myPrefs.Trinket1Use != CRSettingsBMSVMM.TrinketsUse.Manual
                    && nextTrinketUseAllowed <= DateTime.Now, Trinket1()),
                new Decorator(ret => gotTarget
                    && (!BurstKeySettings.myPrefs.useBurstMode || (BurstKeySettings.myPrefs.useBurstMode && !BurstKeySettings.myPrefs.useBurstTrinket2))
                    && CRSettingsBMSVMM.myPrefs.Trinket2Use != CRSettingsBMSVMM.TrinketsUse.Manual
                    && nextTrinketUseAllowed <= DateTime.Now, Trinket2()),
                new Decorator(ret => gotTarget
                    && (!BurstKeySettings.myPrefs.useBurstMode || (BurstKeySettings.myPrefs.useBurstMode && !BurstKeySettings.myPrefs.useBurstEngiGloves))
                    && CRSettingsBMSVMM.myPrefs.GlovesChoice != CRSettingsBMSVMM.useEngiGloves.Manual
                    && nextEngiGlovesUseAllowed <= DateTime.Now, EngineerGloves()),
               new Decorator(ret => gotTarget 
                    && CRSettingsBMSVMM.myPrefs.useVirmenPotions 
                    && !StyxWoW.Me.CurrentTarget.Name.Contains("Dummy") 
                    && isBoss, VirmenPotion()),
                ExploTrapSingle(),
                Cast("Arcane Shot", ret => gotTarget && StyxWoW.Me.FocusPercent > CRSettingsBMSVMM.myPrefs.useArcaneFocus),
                new Decorator(ret => gotTarget && IsWoWBoss(Me.CurrentTarget) && Me.CurrentTarget.InLineOfSight, SnakeTrap()),
                Cast("Cobra Shot", ret => gotTarget && StyxWoW.Me.FocusPercent <= 45 && Me.Level >= 81),
                Cast("Steady Shot", ret => gotTarget && StyxWoW.Me.FocusPercent <= 45 && Me.Level < 81)
                        )));
        }
        Composite CreateBMAoe()
        {
            return new PrioritySelector(
                new Decorator(ret => gotTarget && CRSettingsBMSVMM.myPrefs.MisdirectChoice == CRSettingsBMSVMM.Misdirect.Auto && LastSpell != "Misdirection", CreateMisdirectionBehavior()),
                Cast("Revive Pet", ret => StyxWoW.Me.Pet != null && StyxWoW.Me.Pet.IsDead),
                Cast("Mend Pet", ret => StyxWoW.Me.GotAlivePet && StyxWoW.Me.Pet.HealthPercent <= CRSettingsBMSVMM.myPrefs.useMendPet && !StyxWoW.Me.Pet.HasAura("Mend Pet")),
                ExploTrapMulti(),
                Cast("Kill Command", ret => gotTarget && Me.GotAlivePet
                     && Me.Pet.InLineOfSight
                     && Me.Pet.IsWithinMeleeRangeOf(Me.CurrentTarget)
                     && !spellOnCooldown("Kill Command")),
                new Decorator(ret => gotTarget && buffExists(THRILL_OF_THE_HUNT, Me), ThrillAoeRotation()),
                CreateMultiShotBehavior(),
                CreateTalent90Behavior(),
                SnakeTrap(),
                Cast("Cobra Shot", ret => gotTarget && StyxWoW.Me.FocusPercent < 40 && Me.Level >= 81),
                Cast("Steady Shot", ret => gotTarget && StyxWoW.Me.FocusPercent <= 45 && Me.Level < 81)
                );
        }
        #endregion

        Composite ThrillRoation()
        {
            return new PrioritySelector(
                Cast("Arcane Shot", ret => gotTarget),
                Cast("Cobra Shot", ret => gotTarget && Me.FocusPercent < 10 && Me.Level >= 81),
                Cast("Steady Shot", ret => gotTarget && Me.FocusPercent < 10 && Me.Level < 81)
                );
        }
        Composite ThrillAoeRotation()
        {
            return new PrioritySelector(
                new Decorator(ret => gotTarget && CRSettingsBMSVMM.myPrefs.MisdirectChoice == CRSettingsBMSVMM.Misdirect.Auto && LastSpell != "Misdirection", CreateMisdirectionBehavior()),
                CreateMultiShotBehavior(),
                Cast("Cobra Shot", ret => gotTarget && Me.FocusPercent < 20 && Me.Level >= 81),
                Cast("Steady Shot", ret => gotTarget && Me.FocusPercent < 20 && Me.Level < 81)
                );
        }
    }
}
